<?php

declare(strict_types=1);

namespace app\shop\service\third\wechat;

use sheep\exception\SheepException;
use sheep\exception\SheepDebugException;
use app\shop\facade\Wechat;
use Ramsey\Uuid\Uuid;
use sheep\facade\Auth;
use sheep\model\ThirdOauth;


class MiniProgram
{
    public $wechat;
    protected $request;
    protected $payload;

    public function __construct($payload = [])
    {
        $this->payload = $payload;
        $this->wechat = Wechat::miniProgram();
    }

    // 小程序登录
    public function login()
    {
        // https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01

        // if (empty($this->payload['code'])) {
        //     throw new SheepDebugException('缺少code参数');
        // }
        // $decryptData = $this->wechat->phone_number->getUserPhoneNumber($this->payload['code']);

        if (empty($this->payload['sessionId'])) {
            throw (new SheepException)->setMessage('未获取到登陆态, 请重试', -1);
        }

        $sessionData = cache()->store('persistent')->get($this->payload['sessionId']);

        if (empty($sessionData)) {
            throw (new SheepException)->setMessage('登陆态已过期, 请重试', -1);
        }

        $wechatUser = [
            'openid' => $sessionData['openid'],
            'unionid' => $sessionData['unionid'] ?? '',
            'mobile' => '',
            'avatar' => '',
            'nickname' => '',
        ];
        return $wechatUser;
    }

    public function bind()
    {
        if (empty($this->payload['sessionId'])) {
            throw (new SheepException)->setMessage('未获取到登陆态, 请重试', -1);
        }

        $sessionData = cache()->store('persistent')->get($this->payload['sessionId']);

        if (empty($sessionData)) {
            throw (new SheepException)->setMessage('登陆态已过期, 请重试', -1);
        }

        $wechatUser = [
            'openid' => $sessionData['openid'],
            'unionid' => $sessionData['unionid'] ?? '',
            'avatar' => '',
            'nickname' => '',
        ];
        return $wechatUser;
    }

    // 解密微信小程序手机号
    public function getUserPhoneNumber()
    {
        if (empty($this->payload['code'])) {
            throw new SheepDebugException('缺少code参数');
        }

        $decryptData = $this->wechat->phone_number->getUserPhoneNumber($this->payload['code']);

        if (empty($decryptData) || $decryptData['errcode'] !== 0) {
            throw new SheepException('获取失败,请重试');
        }
        $phoneInfo = $decryptData['phone_info'];
        if ($phoneInfo['countryCode'] !== '86') {
            throw new SheepException('仅支持大陆地区手机号');
        }
        return $phoneInfo['purePhoneNumber'];
    }

    private function getPurePhoneNumber($decryptData)
    {
        if (empty($decryptData)) {
            throw (new SheepException)->setMessage('获取失败,请重试', -1);
        }

        if ($decryptData['countryCode'] !== '86') {
            throw new SheepException('仅支持大陆地区手机号');
        }
        return $decryptData['purePhoneNumber'];
    }

    /**
     * 获取session_id, 缓存 session_key, openid (unionid), 自动登录
     *
     * @return string
     */
    public function getSessionId()
    {
        if (empty($this->payload['code'])) {
            throw new SheepDebugException('缺少code参数');
        }

        $decryptData = $this->wechat->auth->session($this->payload['code']);

        if (!empty($decryptData['errmsg'])) {
            throw new SheepException($decryptData['errmsg']);
        }

        if (empty($decryptData['session_key'])) {
            throw new SheepException('未获取到登陆态, 请重试');
        }

        $auto_login = $this->payload['auto_login'] ?? false;

        // 自动登录流程
        if ($auto_login) {
            $oauthInfo = ThirdOauth::getByOpenid($decryptData['openid']);
            if ($oauthInfo && $oauthInfo->user_id) {
                Auth::guard('user')->loginUsingId($oauthInfo->user_id);
            }
        }

        $session_id = (string) Uuid::uuid4();
        cache()->store('persistent')->tag('session_id')->set($session_id, $decryptData, 60 * 60 * 24 * 7);   // session_key缓存保留一周
        return ['session_id' => $session_id, 'auto_login' => $auto_login];
    }
}
